package shortcircuit.basics;

import shortcircuit.Display;
import shortcircuit.basics.block.*;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;

/**
 * This class will control all of the settings related to the cells in the game. <p>
 * This class contains the location of the cell, the block that the cell could hold,
 * whether the cell is hoverable, and whether the cell is within the current translation path.
 * 
 * @author David Li
 */
public class Cell implements Element
{
	private Block _Block;
	private Point2D _Location; //no longer used
	private boolean  isHoverable, isHovered, isWithinPath, isSelected;
	
	/**
	 * Draws the border of the cell and gets the graphics from the contained block if it exists.
	 * 
	 * @author Kevin Lewi
	 */
	public void getGraphics(Graphics g)
	{
		if(isSelected)
			g.drawImage(Display.selectedBlockGlowImage, -5, -5, null);
		float[] hoverBlockScales = { 2, 2, 2, 1.0f};
		float[] regBlockScales = {1.0f, 1.0f, 1.0f, 1.0f};
		if(hasBlock() && (isHovered || isSelected))
			getBlock().scales = hoverBlockScales;
		else if(hasBlock())
			getBlock().scales = regBlockScales;
		if(hasBlock())
		{
			_Block.getGraphics(g);
		}
	}
	
	/**
	 * Draws the border of the cell and gets the graphics from the contained block if it exists.<p>
	 * This method is different from the original constructor in that it can
	 * draw the true block regardless of hovering and selected statuses.
	 * 
	 * @param ignoreStatus Whether or not the statuses should be ignored.
	 * @author Kevin Lewi
	 */
	public Graphics getGraphics(Graphics g, boolean ignoreStatus)
	{
		if(hasBlock())
			_Block.getGraphics(g);
		return g;
	}
	
	/**
	 * Returns whether the cell is currently hoverable or not.
	 * 
	 * @return Whether the cell is hoverable
	 * 
	 * @author David Li
	 */
	public boolean isHoverable(){
		return isHoverable;
	}
	
	/**
	 * Sets whether the cell is hoverable or not.
	 * 
	 * @param isHoverable Whether the cell is hoverable
	 * 
	 * @author David Li
	 */
	public void setHoverable(boolean isHoverable){
		this.isHoverable = isHoverable;
	}
	
	/**
	 * Returns whether the cell is currently hovered or not.
	 * 
	 * @return Whether the cell is hovered
	 * 
	 * @author Kevin Lewi
	 */
	public boolean isHovered(){
		return isHovered;
	}
	
	/**
	 * Sets whether the cell is hovered or not.
	 * 
	 * @param isHoverable Whether the cell is hovered
	 * 
	 * @author Kevin Lewi
	 */
	public void setHovered(boolean isHoverable){
		this.isHovered = isHoverable;
	}
	
	/**
	 * Returns whether the cell is within the translation path or not.
	 * 
	 * @return Whether the cell is within the translation path
	 * 
	 * @author David Li
	 */
	public boolean isWithinPath(){
		return isWithinPath;
	}
	
	/**
	 * Sets whether the cell is within the translation path or not.
	 * 
	 * @param isWithinPath Whether the cell is within the translation path
	 * 
	 * @author David Li
	 */
	public void setWithinPath(boolean isWithinPath){
		this.isWithinPath = isWithinPath;
	}
	/**
	 * Returns whether the cell is currently selected or not.
	 * 
	 * @return Whether the cell is selected or not
	 * 
	 * @author David Li
	 */
	public boolean isSelected(){
		return isSelected;
	}
	
	/**
	 * Sets whether the cell is currently selected or not.
	 * 
	 * @param isWithinPath Whether the cell is selected or not
	 * 
	 * @author David Li
	 */
	public void setSelected(boolean isSelected){
		this.isSelected = isSelected;
	}
	
	/**
	 * Sets which block the cell is holding, if any.
	 * 
	 * @param theBlock The block the cell is holding
	 * 
	 * @author David Li
	 */
	public void setBlock(Block theBlock)
	{
		_Block = theBlock;
	}
	
	/**
	 * Returns the block the cell is holding, if any.
	 * 
	 * @return The block the cell is holding
	 * 
	 * @author David Li
	 */
	public Block getBlock(){
		return _Block;
	}
	
	/**
	 * Returns whether the block is holding a block or not.
	 * 
	 * @return Whether the block is holding a block
	 * 
	 * @author David Li
	 */
	public boolean hasBlock(){
		if(_Block == null)
			return false;
		if(_Block.getClass().getName().equals(Block0.class.getName()))
			return false;
		return true;
	}
	
	/**
	 * Removes the block that the cell is holding.
	 * 
	 * @author David Li
	 */
	public void removeBlock(){
		_Block = new Block0();
	}
	
	/**
	 * Returns the x position of the cell.
	 * 
	 * @return The x position of the cell
	 * @deprecated
	 * @author David Li
	 */
	public int getX(){
		return (int)_Location.getX();
	}
	
	/**
	 * Returns the y position of the cell.
	 * 
	 * @return The y position of the cell
	 * @deprecated
	 * @author David Li
	 */
	public int getY(){
		return (int)_Location.getY();
	}
	
	/**
	 * Returns the assigned element number of the cell.
	 * 
	 * @return The assigned element number of the cell in integer form
	 * @deprecated
	 * @author Kevin Lewi
	 */
	public int getNumber()
	{
		return (int) _Location.getY() * 10 + (int) _Location.getX();
	}
}
